"""Tophub API 集成模块
提供实时获取和缓存热榜数据的功能
"""
import asyncio
import logging
from datetime import datetime, timedelta
from typing import List, Dict, Any, Optional
from motor.motor_asyncio import AsyncIOMotorClient
import redis

from ..services.tophub_service import TophubService
from ..models.hot_data import Platform
from .config import settings

logger = logging.getLogger(__name__)


class TophubIntegration:
    """Tophub数据集成类"""
    
    def __init__(self):
        """初始化"""
        # MongoDB连接
        self.mongo_client = AsyncIOMotorClient(settings.mongodb_uri)
        self.db = self.mongo_client[settings.mongodb_db]
        
        # Redis连接
        self.redis_client = redis.Redis(
            host=settings.redis_host,
            port=settings.redis_port,
            password=settings.redis_password,
            db=settings.redis_db,
            decode_responses=True
        )
        
        # Tophub服务
        self.tophub_service = TophubService()
        
        # 平台映射
        self.platform_map = {
            Platform.ZHIHU: 'zhihu',
            Platform.WEIBO: 'weibo',
            Platform.BAIDU: 'baidu',
            Platform.TOUTIAO: 'toutiao',
            Platform.BILIBILI: 'bilibili',
            Platform.DOUYIN: 'douyin',
        }
    
    async def fetch_and_store_platform_data(self, platform: Platform) -> int:
        """获取并存储单个平台的数据
        
        Args:
            platform: 平台枚举
            
        Returns:
            存储的数据条数
        """
        platform_name = self.platform_map.get(platform)
        if not platform_name:
            logger.warning(f"不支持的平台: {platform}")
            return 0
        
        try:
            # 从Tophub获取数据
            async with self.tophub_service as service:
                data = await service.get_node_data(platform_name)
                if not data:
                    logger.warning(f"无法从Tophub获取 {platform_name} 数据")
                    return 0
                
                # 标准化数据
                normalized = service.normalize_data(platform_name, data)
                
                # 转换为MongoDB格式
                collection = self.db[f"{platform_name}_hot_items"]
                documents = []
                
                now = datetime.utcnow()
                for item in normalized:
                    doc = {
                        'title': item['title'],
                        'url': item['url'],
                        'rank': item['rank'],
                        'heat_value': str(item.get('heat_value', 0)),
                        'heat_value_numeric': int(item.get('heat_value', 0)),
                        'platform': platform_name,
                        'category': 'hot',
                        'crawled_at': now,
                        'updated_at': now,
                        'excerpt': item.get('description', '')[:200],
                        'source': 'tophub',
                        'extra': item.get('extra', {})
                    }
                    documents.append(doc)
                
                if documents:
                    # 清除旧数据（可选：保留历史数据）
                    # await collection.delete_many({'crawled_at': {'$lt': now - timedelta(hours=24)}})
                    
                    # 插入新数据
                    try:
                        result = await collection.insert_many(documents)
                        logger.info(f"成功存储 {len(result.inserted_ids)} 条 {platform_name} 数据")
                        return len(result.inserted_ids)
                    except Exception as e:
                        logger.error(f"存储 {platform_name} 数据失败: {e}")
                        return 0
                
        except Exception as e:
            logger.error(f"获取 {platform_name} 数据失败: {e}")
            return 0
        
        return 0
    
    async def fetch_all_platforms(self) -> Dict[str, int]:
        """获取所有平台的数据
        
        Returns:
            各平台存储的数据条数
        """
        results = {}
        
        for platform in Platform:
            if platform in self.platform_map:
                count = await self.fetch_and_store_platform_data(platform)
                results[platform.value] = count
                # 避免请求过快
                await asyncio.sleep(1)
        
        return results
    
    async def should_refresh_data(self, platform: Platform) -> bool:
        """检查是否需要刷新数据
        
        Args:
            platform: 平台枚举
            
        Returns:
            是否需要刷新
        """
        platform_name = self.platform_map.get(platform)
        if not platform_name:
            return False
        
        # 检查最新数据的时间
        collection = self.db[f"{platform_name}_hot_items"]
        latest = await collection.find_one(
            sort=[('crawled_at', -1)]
        )
        
        if not latest:
            return True
        
        # 如果数据超过10分钟，则需要刷新
        age = datetime.utcnow() - latest.get('crawled_at', datetime.min)
        return age > timedelta(minutes=10)
    
    async def get_or_fetch_data(self, platforms: List[Platform]) -> Dict[str, Any]:
        """获取数据，必要时从Tophub拉取
        
        Args:
            platforms: 平台列表
            
        Returns:
            数据结果
        """
        results = {}
        
        for platform in platforms:
            # 检查是否需要刷新
            if await self.should_refresh_data(platform):
                logger.info(f"刷新 {platform.value} 数据...")
                await self.fetch_and_store_platform_data(platform)
            
            # 获取数据
            platform_name = self.platform_map.get(platform)
            if platform_name:
                collection = self.db[f"{platform_name}_hot_items"]
                cursor = collection.find().sort('rank', 1).limit(50)
                items = []
                async for item in cursor:
                    item['item_id'] = str(item.pop('_id'))
                    items.append(item)
                results[platform.value] = items
        
        return results


# 全局实例
tophub_integration = TophubIntegration()


async def refresh_hot_data_background():
    """后台任务：定期刷新热榜数据"""
    while True:
        try:
            logger.info("开始后台刷新热榜数据...")
            results = await tophub_integration.fetch_all_platforms()
            logger.info(f"热榜数据刷新完成: {results}")
        except Exception as e:
            logger.error(f"后台刷新失败: {e}")
        
        # 每10分钟刷新一次
        await asyncio.sleep(600)